package com.shujia.java.day21.demo1;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws Exception {
        //通过Class获取这个类  参数给具体的指定
        //反射获取一个类 通过scr下第一级目录以及以及往下找
        //Class<?> student = Class.forName("com.shujia.java.day21.demo1.Student");
        //反射获取名字
        //System.out.println(student.getName());
        show1();
        System.out.println("--------------------------------------");
        show2();
        System.out.println("--------------------------------------");
        show3();
        System.out.println("--------------------------------------");
        show4();
        System.out.println("--------------------------------------");
        show5();
        System.out.println("--------------------------------------");
        show6();
        System.out.println("--------------------------------------");
        show7();
    }

    //反射获取属性
    public static void show1() throws Exception {
        Class<?> student = Class.forName("com.shujia.java.day21.demo1.Student");
        //getFields获取所有公共属性
//        Field[] fields = student.getFields();
//        for (Field f:fields) {
//            System.out.println(f);
//        }
        //获取所有属性
//        Field[] fields = student.getDeclaredFields();
//        for (Field f : fields) {
//            System.out.println(f);
//        }
        //获取一个属性  getField只能获取一个public的属性
        Field name = student.getDeclaredField("name");
        name.setAccessible(true);
        System.out.println(name);
    }

    //反射赋值
    public static void show2() throws Exception {
        //获取类的模型
        Class<?> student = Class.forName("com.shujia.java.day21.demo1.Student");
        //获取共有属性赋值
        //Field test = student.getDeclaredField("test");
        //获取私有属性赋值
        Field test = student.getDeclaredField("name");
        //获取私有属性不能直接赋值
        //想要赋值该怎么办
        //私有转公有 （免疫检查）
        test.setAccessible(true);
        //Field操作属性get set
        //set(test所在的类,所要赋的值)
        Object o = student.newInstance();
        test.set(o, "Test");
        System.out.println(test.get(o));


    }

    //反射获取构造
    public static void show3() throws Exception {
        //获取类的模型
        Class<?> student = Class.forName("com.shujia.java.day21.demo1.Student");
        //获取所有公有构造
//        Constructor<?>[] constructors = student.getConstructors();
//        for (Constructor c:constructors) {
//            System.out.println(c);
//        }
        //获取所有构造
//        Constructor<?>[] constructors = student.getDeclaredConstructors();
//        for (Constructor c:constructors) {
//            System.out.println(c);
//        }
        //获取一个构造 获取无参构造
//        Constructor<?> constructor = student.getDeclaredConstructor();
//        System.out.println(constructor);
        //怎么获取指定构造？以参数来获取构造
        //参数需要类型加上.class
        Constructor<?> constructor = student.getDeclaredConstructor(String.class, int.class, String.class);
        System.out.println(constructor);
    }

    //反射使用构造创建对象
    public static void show4() throws Exception {
        //获取类的模型
        Class<?> student = Class.forName("com.shujia.java.day21.demo1.Student");
        //获取私有构造
        Constructor<?> declaredConstructor = student.getDeclaredConstructor(String.class, int.class);
        //私有构造能不能直接使用? 先免疫检查
        declaredConstructor.setAccessible(true);
        //创建实例
        Object o = declaredConstructor.newInstance("张三", 18);
        Student s = (Student) o;
        System.out.println(s.toString());
    }

    //反射获取方法
    public static void show5() throws Exception {
        //获取类的模型
        Class<?> student = Class.forName("com.shujia.java.day21.demo1.Student");
        //获取所有公有方法 包括父类
//        Method[] methods = student.getMethods();
//        for (Method m:methods) {
//            System.out.println(m);
//        }
        //获取自己所有的方法
//        Method[] methods = student.getDeclaredMethods();
//        for (Method m:methods) {
//            System.out.println(m);
//        }
        //获取一个方法
        Method declaredMethod = student.getDeclaredMethod("show");
        System.out.println(declaredMethod);
    }

    //反射使用方法
    public static void show6() throws Exception {
        //获取类的模型
        Class<?> student = Class.forName("com.shujia.java.day21.demo1.Student");
        //获取一个方法
        Method declaredMethod = student.getDeclaredMethod("show");
        //私有不能直接用 免疫检查
        declaredMethod.setAccessible(true);
        //创建实例
        Object o = student.newInstance();
        declaredMethod.invoke(o);
    }

    //反射创建对象
    public static void show7() throws Exception {
        //获取类的模型
        Class<?> student = Class.forName("com.shujia.java.day21.demo1.Student");
        //创建对象的实例
        Object o = student.newInstance();
        //需要进行向下转型
        Student stu=(Student)o;
        stu.setName("张三");
        stu.setAge(18);
        stu.setSex("男");
        System.out.println(stu.toString());

    }

}
